const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const JSBackend = require('./js_backend');

// 读取package.json中的版本号
const packageJson = require('./package.json');
const APP_VERSION = packageJson.version;

class JSServer {
  constructor(port = 8080) {
    this.app = express();
    this.port = port;
    this.backend = new JSBackend();
    this.setupMiddleware();
    this.setupRoutes();
  }

  // 统一的资源路径处理
  getResourcePath(relativePath) {
    if (process.resourcesPath) {
      // 打包后环境
      const asarPath = path.join(process.resourcesPath, 'app.asar', relativePath);
      if (fs.existsSync(asarPath)) return asarPath;
      
      const appPath = path.join(process.resourcesPath, 'app', relativePath);
      if (fs.existsSync(appPath)) return appPath;
      
      return null;
    } else {
      // 开发环境
      return path.join(__dirname, relativePath);
    }
  }

  // 获取uploads目录路径（适应打包和开发环境）
  getUploadsDir() {
    // 检查是否为打包环境（更准确的判断）
    const isPackaged = process.mainModule && process.mainModule.filename.indexOf('app.asar') !== -1;
    
    if (isPackaged) {
      // 打包后环境：使用用户数据目录
      const { app } = require('electron');
      const userDataPath = app.getPath('userData');
      return path.join(userDataPath, 'uploads');
    } else {
      // 开发环境：使用项目目录
      return path.join(__dirname, 'uploads');
    }
  }

  // 从asar中读取文件内容
  readFromAsar(filePath) {
    try {
      let asar;
      try {
        asar = require('@electron/asar');
      } catch (e) {
        asar = require('asar');
      }
      
      const asarPath = path.join(process.resourcesPath, 'app.asar');
      if (fs.existsSync(asarPath)) {
        return asar.extractFile(asarPath, filePath);
      }
    } catch (error) {
      console.log('从asar读取失败:', error.message);
    }
    return null;
  }

  setupMiddleware() {
    // 静态文件服务
    const staticPath = this.getResourcePath('static');
    if (staticPath && fs.existsSync(staticPath)) {
      this.app.use('/static', express.static(staticPath));
    }
    
    // 解析JSON和表单数据
    this.app.use(express.json());
    this.app.use(express.urlencoded({ extended: true }));

    // 文件上传配置
    const self = this; // 保存this引用
    const storage = multer.diskStorage({
      destination: (req, file, cb) => {
        const uploadsDir = self.getUploadsDir();
        
        if (!fs.existsSync(uploadsDir)) {
          fs.mkdirSync(uploadsDir, { recursive: true });
        }
        cb(null, uploadsDir);
      },
      filename: (req, file, cb) => {
        // 保持原文件名，添加时间戳避免冲突，处理中文编码
        const timestamp = Date.now();
        const originalName = Buffer.from(file.originalname, 'latin1').toString('utf8');
        const ext = path.extname(originalName);
        const name = path.basename(originalName, ext);
        // 使用安全的文件名，移除特殊字符
        const safeName = name.replace(/[^\w\u4e00-\u9fa5.-]/g, '_');
        cb(null, `${safeName}_${timestamp}${ext}`);
      }
    });

    this.upload = multer({ 
      storage,
      fileFilter: (req, file, cb) => {
        const allowedTypes = ['.xlsx', '.xls', '.csv'];
        const ext = path.extname(file.originalname).toLowerCase();
        if (allowedTypes.includes(ext)) {
          cb(null, true);
        } else {
          cb(new Error('不支持的文件类型'));
        }
      },
      limits: {
        fileSize: 50 * 1024 * 1024 // 50MB限制
      }
    });
  }

  setupRoutes() {
    // 主页
    this.app.get('/', (req, res) => {
      try {
        // 尝试读取模板文件
        if (process.resourcesPath) {
          // 打包后环境，从asar读取
          const templateContent = this.readFromAsar('templates/index.html');
          if (templateContent) {
            res.setHeader('Content-Type', 'text/html');
            return res.send(templateContent);
          }
        } else {
          // 开发环境，直接读取文件
          const templatePath = path.join(__dirname, 'templates', 'index.html');
          if (fs.existsSync(templatePath)) {
            return res.sendFile(templatePath);
          }
        }
        
        // 降级到内联HTML
        res.send(this.getInlineHTML());
      } catch (error) {
        console.error('加载主页模板错误:', error);
        res.send(this.getInlineHTML());
      }
    });

    // 文件上传
    this.app.post('/upload', this.upload.single('file'), (req, res) => {
      try {
        if (!req.file) {
          return res.status(400).json({ error: '没有上传文件' });
        }

        const filePath = req.file.path;
        const fileName = req.file.originalname;
        
        // 文件上传成功，继续处理

        // 解析文件
        const parseResult = this.backend.parseExcelFile(filePath);
        
        res.json({
          success: true,
          message: '文件上传并解析成功',
          file: {
            name: fileName,
            path: filePath,
            size: req.file.size
          },
          data: {
            headers: parseResult.headers,
            rowCount: parseResult.rowCount,
            preview: parseResult.data.slice(0, 5) // 预览前5行
          }
        });

      } catch (error) {
        console.error('文件上传处理错误:', error);
        res.status(500).json({ 
          error: '文件处理失败', 
          details: error.message 
        });
      }
    });

    // 转换为数据库
    this.app.post('/convert', async (req, res) => {
      try {
        console.log('开始转换请求:', req.body);
        const { filePath, dbName, tableName, password } = req.body;

        if (!filePath || !dbName || !tableName) {
          console.log('缺少必要参数:', { filePath, dbName, tableName });
          return res.status(400).json({ error: '缺少必要参数' });
        }

        console.log('解析文件:', filePath);
        // 解析文件
        const parseResult = this.backend.parseExcelFile(filePath);
        console.log('解析结果:', { headers: parseResult.headers.length, rows: parseResult.data.length });
        
        // 同时创建两个数据库：普通SQLite和SQLCipher加密数据库
        const outputDir = this.getUploadsDir();
        console.log('输出目录:', outputDir);
        
        // 创建普通SQLite数据库
        const normalSqliteFile = path.join(outputDir, `${dbName}.db`);
        console.log('创建普通数据库:', normalSqliteFile);
        const normalResult = await this.backend.exportToSQLite(parseResult, normalSqliteFile, tableName);
        console.log('普通数据库创建完成:', normalResult);
        
        // 创建SQLCipher加密数据库（使用用户提供的密码）
        const encryptedSqliteFile = path.join(outputDir, `${dbName}_encrypted.db`);
        console.log('创建加密数据库:', encryptedSqliteFile);
        const encryptedResult = await this.backend.exportToSQLCipher(parseResult, encryptedSqliteFile, tableName, password);
        console.log('加密数据库创建完成:', encryptedResult);

        const result = {
          success: true,
          message: '转换成功，已生成普通数据库和加密数据库',
          database: {
            name: dbName,
            tables: [{
              name: tableName,
              columns: parseResult.headers.length,
              rows: parseResult.data.length
            }],
            // 普通数据库信息
            normal: {
              file: normalSqliteFile,
              filename: `${dbName}.db`,
              type: 'SQLite'
            },
            // 加密数据库信息
            encrypted: {
              file: encryptedSqliteFile,
              filename: `${dbName}_encrypted.db`,
              cipher: 'SQLCipher',
              password: password
            }
          }
        };

        console.log('返回结果:', result);
        res.json(result);

      } catch (error) {
        console.error('转换错误:', error);
        res.status(500).json({ 
          error: '转换失败', 
          details: error.message 
        });
      }
    });

    // 获取数据库信息
    this.app.get('/database/:name', (req, res) => {
      try {
        const dbName = req.params.name;
        const info = this.backend.getDatabaseInfo(dbName);
        
        if (!info) {
          return res.status(404).json({ error: '数据库不存在' });
        }

        res.json(info);
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });

    // 查询表数据
    this.app.get('/database/:dbName/table/:tableName', (req, res) => {
      try {
        const { dbName, tableName } = req.params;
        const limit = parseInt(req.query.limit) || 100;
        
        const result = this.backend.query(dbName, tableName, limit);
        res.json(result);
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });

    // 下载文件
    this.app.get('/download/:filename', (req, res) => {
      try {
        const filename = req.params.filename;
        const uploadsDir = this.getUploadsDir();
        const filePath = path.join(uploadsDir, filename);
        
        console.log('下载请求:', {
          filename: filename,
          uploadsDir: uploadsDir,
          filePath: filePath,
          exists: fs.existsSync(filePath)
        });
        
        if (!fs.existsSync(filePath)) {
          console.log('文件不存在:', filePath);
          console.log('uploads目录内容:', fs.readdirSync(uploadsDir));
          return res.status(404).json({ error: '文件不存在' });
        }

        console.log('开始下载文件:', filePath);
        res.download(filePath, filename, (err) => {
          if (err) {
            console.error('下载文件错误:', err);
          } else {
            console.log('文件下载成功:', filename);
          }
        });
      } catch (error) {
        console.error('下载路由错误:', error);
        res.status(500).json({ error: error.message });
      }
    });

    // 健康检查
    this.app.get('/health', (req, res) => {
      res.json({ 
        status: 'ok', 
        timestamp: new Date().toISOString(),
        uptime: process.uptime()
      });
    });

    // 错误处理
    this.app.use((error, req, res, next) => {
      console.error('服务器错误:', error);
      res.status(500).json({ 
        error: '服务器内部错误', 
        details: error.message 
      });
    });

    // 404处理
    this.app.use((req, res) => {
      res.status(404).json({ error: '页面不存在' });
    });
  }

  // 内联HTML作为降级方案
  getInlineHTML() {
    return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Excel转SQLite数据库工具</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
    <style>
        body {
            font-family: 'Microsoft YaHei', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f8f9fa;
            padding-top: 20px;
        }
        .container {
            max-width: 800px;
            background-color: white;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
            padding: 30px;
            margin-bottom: 30px;
        }
        .header {
            text-align: center;
            margin-bottom: 30px;
        }
        .header h1 {
            color: #343a40;
            font-weight: 600;
        }
        .drop-area {
            border: 2px dashed #6c757d;
            border-radius: 10px;
            padding: 30px 15px;
            text-align: center;
            cursor: pointer;
            transition: all 0.3s;
            margin-bottom: 15px;
        }
        .drop-area:hover, .drop-area.dragover {
            border-color: #007bff;
            background-color: rgba(0, 123, 255, 0.05);
        }
        .drop-area i {
            font-size: 36px;
            color: #6c757d;
            margin-bottom: 10px;
        }
        .drop-area p {
            color: #6c757d;
            margin-bottom: 0;
        }
        .form-section {
            display: none;
            margin-top: 30px;
        }
        .result-section {
            display: none;
            margin-top: 30px;
        }
        .btn-primary {
            background-color: #007bff;
            border-color: #007bff;
        }
        .btn-primary:hover {
            background-color: #0069d9;
            border-color: #0062cc;
        }
        .btn-success {
            background-color: #28a745;
            border-color: #28a745;
        }
        .btn-success:hover {
            background-color: #218838;
            border-color: #1e7e34;
        }
        .progress {
            height: 25px;
            margin-top: 20px;
            margin-bottom: 20px;
        }
        .progress-bar {
            font-size: 14px;
            line-height: 25px;
        }
        .alert {
            margin-top: 20px;
        }
        .file-info {
            margin-top: 15px;
            padding: 10px;
            background-color: #f8f9fa;
            border-radius: 5px;
            border: 1px solid #e9ecef;
        }
        .download-btn {
            margin-right: 10px;
            margin-bottom: 10px;
        }
        .no-list-style {
            list-style-type: none;
            padding-left: 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>Excel转SQLite数据库工具</h1>
            <p class="text-muted">For Android v${APP_VERSION}</p>
        </div>
        
        <div id="upload-section">
            <div id="drop-area" class="drop-area">
                <i class="fas fa-file-excel"></i>
                <h5>拖拽Excel或CSV文件到这里</h5>
                <p>或者点击选择文件</p>
                <input type="file" id="file-input" style="display: none" accept=".xlsx,.csv">
            </div>
            <div id="file-info" class="file-info" style="display: none">
                <div class="d-flex justify-content-between align-items-center">
                    <div>
                        <i class="fas fa-file-excel text-success me-2"></i>
                        <span id="file-name"></span>
                    </div>
                    <button class="btn btn-sm btn-outline-danger" id="remove-file">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
            </div>
            
            <div id="feature-intro" class="mt-4 p-3 bg-light border rounded">
                <h5 class="mb-3">提示：</h5>
                <ol class="no-list-style">
                    <li>1️⃣ 前往 <a href="https://gitee.com/zwo-wifi/zwoastro-image-and-db" class="external-link">gitee仓库</a> 下载 excel/csv 文件；</li>
                    <li>2️⃣ 按步骤生成加密数据库，并上传至网盘存档；</li>
                    <li>3️⃣ 通知开发更新项目；</li>
                    <li>🏫 小工具由 AI 生成，欢迎<a href="https://gitee.com/lygdhy/android_excel2db_translator" class="external-link">交流学习</a>；</li>
                </ol>
            </div>
        </div>
        
        <div id="form-section" class="form-section">
            <h4 class="mb-4">确认信息</h4>
            <form id="convert-form">
                <div class="mb-3">
                    <label for="version" class="form-label">数据库版本</label>
                    <input type="text" class="form-control" id="version" name="version" required>
                    <div class="form-text">版本格式为 n.n.n（n为数字）</div>
                </div>
                <div class="mb-3">
                    <label for="password" class="form-label">加密密码</label>
                    <input type="text" class="form-control" id="password" name="password" value="pwc9UhwS0I9t0x74" readonly>
                    <div class="form-text">固定密码，不可修改</div>
                </div>
                <div class="d-grid gap-2">
                    <button type="submit" class="btn btn-primary" id="convert-btn">开始转换</button>
                </div>
            </form>
        </div>
        
        <div id="progress-section" style="display: none">
            <h4 class="mb-4">处理中...</h4>
            <div class="progress">
                <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%" id="progress-bar">0%</div>
            </div>
            <p class="text-center" id="progress-text">正在准备转换...</p>
        </div>
        
        <div id="result-section" class="result-section">
            <div class="alert alert-success">
                <i class="fas fa-check-circle me-2"></i>
                <span id="success-message">转换完成！您可以下载以下文件：</span>
            </div>
            <div class="d-flex flex-wrap mt-4">
                <div class="download-btn">
                    <a href="#" class="btn btn-success" id="download-normal">
                        <i class="fas fa-download me-2"></i>
                        下载普通数据库
                    </a>
                </div>
                <div class="download-btn">
                    <a href="#" class="btn btn-success" id="download-encrypted">
                        <i class="fas fa-lock me-2"></i>
                        下载加密数据库
                    </a>
                </div>
            </div>
            <div class="mt-4">
                <button class="btn btn-outline-primary" id="restart-btn">
                    <i class="fas fa-redo me-2"></i>
                    重新开始
                </button>
            </div>
        </div>
        
        <div id="error-section" style="display: none">
            <div class="alert alert-danger">
                <i class="fas fa-exclamation-triangle me-2"></i>
                <span id="error-message"></span>
            </div>
            <div class="mt-4">
                <button class="btn btn-outline-primary" id="error-restart-btn">
                    <i class="fas fa-redo me-2"></i>
                    重新开始
                </button>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 处理外部链接点击
            document.querySelectorAll('.external-link').forEach(link => {
                link.addEventListener('click', function(e) {
                    e.preventDefault();
                    const url = this.getAttribute('href');
                    if (window.electronAPI) {
                        window.electronAPI.openExternalLink(url);
                    } else {
                        window.open(url, '_blank');
                    }
                });
            });
            
            const dropArea = document.getElementById('drop-area');
            const fileInput = document.getElementById('file-input');
            const fileName = document.getElementById('file-name');
            const fileInfo = document.getElementById('file-info');
            const removeFile = document.getElementById('remove-file');
            const uploadSection = document.getElementById('upload-section');
            const formSection = document.getElementById('form-section');
            const convertForm = document.getElementById('convert-form');
            const versionInput = document.getElementById('version');
            const progressSection = document.getElementById('progress-section');
            const progressBar = document.getElementById('progress-bar');
            const progressText = document.getElementById('progress-text');
            const resultSection = document.getElementById('result-section');
            const downloadNormal = document.getElementById('download-normal');
            const downloadEncrypted = document.getElementById('download-encrypted');
            const restartBtn = document.getElementById('restart-btn');
            const errorSection = document.getElementById('error-section');
            const errorMessage = document.getElementById('error-message');
            const errorRestartBtn = document.getElementById('error-restart-btn');
            
            let selectedFile = null;
            
            // 拖拽事件处理
            ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
                dropArea.addEventListener(eventName, preventDefaults, false);
            });
            
            function preventDefaults(e) {
                e.preventDefault();
                e.stopPropagation();
            }
            
            ['dragenter', 'dragover'].forEach(eventName => {
                dropArea.addEventListener(eventName, highlight, false);
            });
            
            ['dragleave', 'drop'].forEach(eventName => {
                dropArea.addEventListener(eventName, unhighlight, false);
            });
            
            function highlight() {
                dropArea.classList.add('dragover');
            }
            
            function unhighlight() {
                dropArea.classList.remove('dragover');
            }
            
            // 处理文件拖放
            dropArea.addEventListener('drop', handleDrop, false);
            
            function handleDrop(e) {
                const dt = e.dataTransfer;
                const files = dt.files;
                
                if (files.length > 0) {
                    handleFiles(files[0]);
                }
            }
            
            // 点击选择文件
            dropArea.addEventListener('click', () => {
                fileInput.click();
            });
            
            fileInput.addEventListener('change', (e) => {
                if (e.target.files.length > 0) {
                    handleFiles(e.target.files[0]);
                }
            });
            
            // 处理选择的文件
            function handleFiles(file) {
                // 清除之前的错误信息
                errorSection.style.display = 'none';
                resultSection.style.display = 'none';
                
                if (!file.name.endsWith('.xlsx') && !file.name.endsWith('.csv')) {
                    showError('只支持Excel (.xlsx) 或CSV (.csv) 文件');
                    return;
                }
                
                selectedFile = file;
                fileName.textContent = file.name;
                fileInfo.style.display = 'block';
                formSection.style.display = 'block';
                
                // 隐藏功能介绍区域
                document.getElementById('feature-intro').style.display = 'none';
                
                // 从文件名中提取版本号
                extractVersionFromFile(file);
            }
            
            // 从文件名中提取版本号
            function extractVersionFromFile(file) {
                // 从文件名中提取版本号（简化版）
                const fileName = file.name;
                const versionMatch = fileName.match(/v?(\\d+\\.\\d+\\.\\d+)/i);
                if (versionMatch) {
                    versionInput.value = versionMatch[1];
                }
            }
            
            // 移除选择的文件
            removeFile.addEventListener('click', () => {
                resetForm();
            });
            
            // 重置表单
            function resetForm() {
                selectedFile = null;
                fileInput.value = '';
                fileName.textContent = '';
                fileInfo.style.display = 'none';
                formSection.style.display = 'none';
                versionInput.value = '';
            }
            
            // 提交表单开始转换
            convertForm.addEventListener('submit', (e) => {
                e.preventDefault();
                
                if (!selectedFile) {
                    showError('请先选择Excel文件');
                    return;
                }
                
                const version = versionInput.value.trim();
                if (!version) {
                    showError('请输入数据库版本');
                    return;
                }
                
                // 验证版本号格式
                const versionPattern = /^\\d+\\.\\d+\\.\\d+$/;
                if (!versionPattern.test(version)) {
                    showError('版本号格式不正确，应为 n.n.n（n为数字）');
                    return;
                }
                
                // 开始转换
                startConversion();
            });
            
            // 开始转换过程
            function startConversion() {
                uploadSection.style.display = 'none';
                formSection.style.display = 'none';
                progressSection.style.display = 'block';
                
                const formData = new FormData();
                formData.append('file', selectedFile);
                
                // 重置进度条
                updateProgress(0, '准备开始转换...');
                
                // 模拟进度
                let progress = 0;
                const progressInterval = setInterval(() => {
                    if (progress < 10) {
                        progress += 2;
                        updateProgress(progress, '文件解析中...');
                    } else if (progress < 45) {
                        progress += 5;
                        updateProgress(progress, '生成数据库...');
                    } else if (progress < 90) {
                        progress += 3;
                        updateProgress(progress, '数据库加密中...');
                    } else {
                        clearInterval(progressInterval);
                    }
                }, 300);
                
                // 第一步：上传文件
                fetch('/upload', {
                    method: 'POST',
                    body: formData
                })
                .then(response => {
                    if (!response.ok) {
                        return response.json().then(data => {
                            throw new Error(data.error || '文件上传失败');
                        });
                    }
                    return response.json();
                })
                .then(uploadData => {
                    // 第二步：转换为数据库
                    const convertData = {
                        filePath: uploadData.file.path,
                        dbName: 'star_db_' + versionInput.value,
                        tableName: 'star_data',
                        password: document.getElementById('password').value
                    };
                    
                    return fetch('/convert', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(convertData)
                    });
                })
                .then(response => {
                    if (!response.ok) {
                        return response.json().then(data => {
                            throw new Error(data.error || '数据库转换失败');
                        });
                    }
                    return response.json();
                })
                .then(data => {
                    clearInterval(progressInterval);
                    updateProgress(90, '正在完成转换...');
                    
                    // 调试日志
                    console.log('转换结果数据:', data);
                    console.log('data.database:', data.database);
                    console.log('data.database.file:', data.database.file);
                    
                    setTimeout(() => {
                        updateProgress(100, '转换完成！');
                        progressSection.style.display = 'none';
                        resultSection.style.display = 'block';
                        
                        // 更新成功信息，显示记录数
                        const successMessage = document.getElementById('success-message');
                        const rowCount = data.database.tables[0].rows;
                        successMessage.textContent = '转换完成，共' + rowCount + '条记录！您可以下载以下文件：';
                        
                        // 设置下载链接
                        const dbFileName = data.database.normal.file.split('/').pop();
                        downloadNormal.href = '/download/' + dbFileName;
                        
                        if (data.database.encrypted) {
                            const encryptedFileName = data.database.encrypted.file.split('/').pop();
                            downloadEncrypted.href = '/download/' + encryptedFileName;
                        } else {
                            downloadEncrypted.style.display = 'none';
                        }
                    }, 500);
                })
                .catch(error => {
                    clearInterval(progressInterval);
                    progressSection.style.display = 'none';
                    showError(error.message || '转换过程中出错');
                });
            }
            
            // 更新进度条
            function updateProgress(percent, text) {
                progressBar.style.width = \`\${percent}%\`;
                progressBar.textContent = \`\${percent}%\`;
                progressText.textContent = text;
            }
            
            // 显示错误信息
            function showError(message) {
                errorMessage.textContent = message;
                errorSection.style.display = 'block';
                uploadSection.style.display = 'block';
                formSection.style.display = 'none';
                progressSection.style.display = 'none';
                resultSection.style.display = 'none';
            }
            
            // 重新开始按钮
            restartBtn.addEventListener('click', () => {
                resetAll();
            });
            
            errorRestartBtn.addEventListener('click', () => {
                resetAll();
            });
            
            // 完全重置
            function resetAll() {
                resetForm();
                errorSection.style.display = 'none';
                resultSection.style.display = 'none';
                uploadSection.style.display = 'block';
                document.getElementById('feature-intro').style.display = 'block';
            }
        });
    </script>
</body>
</html>`;
  }

  start() {
    return new Promise((resolve, reject) => {
      const server = this.app.listen(this.port, '127.0.0.1', () => {
        const url = `http://127.0.0.1:${this.port}`;
        console.log(`JavaScript服务器启动成功: ${url}`);
        resolve({ server, url, port: this.port });
      });

      server.on('error', (error) => {
        if (error.code === 'EADDRINUSE') {
          console.log(`端口 ${this.port} 被占用，尝试其他端口...`);
          this.port = Math.floor(Math.random() * 10000) + 10000;
          this.start().then(resolve).catch(reject);
        } else {
          reject(error);
        }
      });
    });
  }
}

module.exports = JSServer;